// Package Logger  日志门面设计
// @Description  请填写文件描述（需要改）
// @Author  请填写自己的真是姓名（需要改）  ${DATE} ${TIME}
// @Update  请填写自己的真是姓名（需要改）  ${DATE} ${TIME}
package logger

import (
	"context"
	"fmt"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

type Logger struct {
	ctx     context.Context
	traceId string
	spanId  string
	pSpanId string
	_logger *zap.Logger
}

func New(ctx context.Context, logger *zap.Logger) *Logger {
	var traceId, spanId, pSpanId string
	if ctx.Value("traceid") != nil {
		traceId = ctx.Value("traceid").(string)
	}
	if ctx.Value("spanid") != nil {
		spanId = ctx.Value("spanid").(string)
	}
	if ctx.Value("psapnid") != nil {
		pSpanId = ctx.Value("pspanid").(string)
	}

	return &Logger{
		ctx:     ctx,
		traceId: traceId,
		spanId:  spanId,
		pSpanId: pSpanId,
		_logger: logger,
	}
}

func (l *Logger) Debug(msg string, kv ...interface{}) {
	l.log(zapcore.DebugLevel, msg, kv...)
}

// Info
// @description   info级别日志
// @auths      作者             时间（2019/6/18   10:57 ）
// @param     msg       日志内容带参
// @param     kv        成对的参数
func (l *Logger) Info(msg string, kv ...interface{}) {
	l.log(zapcore.InfoLevel, msg, kv...)
}

func (l *Logger) Warn(msg string, kv ...interface{}) {
	l.log(zapcore.WarnLevel, msg, kv...)
}

func (l *Logger) Error(msg string, kv ...interface{}) {
	l.log(zapcore.ErrorLevel, msg, kv...)
}

func (l *Logger) log(lvl zapcore.Level, msg string, kv ...interface{}) {
	if len(kv)%2 != 0 {
		kv = append(kv, "unknow")
	}

	fields := make([]zap.Field, 0, len(kv)/2)
	for i := 0; i < len(kv); i += 2 {
		fields = append(fields, zap.Any(fmt.Sprintf("%v", kv[i]), kv[i+1]))
	}

	// Zap 写日志前先调用了check方法，判断这个日志级别是否能写入再去写日志的，而且这个check方法我看了一下是有提供外部调用的版本的。
	ce := l._logger.Check(lvl, msg)
	ce.Write(fields...)
}
